package org.wattdepot.modbus.sensor;

import java.net.InetAddress;
import net.wimpi.modbus.core.Modbus;
import net.wimpi.modbus.core.ModbusException;
import net.wimpi.modbus.core.ModbusIOException;
import net.wimpi.modbus.core.ModbusSlaveException;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.ReadMultipleRegistersRequest;
import net.wimpi.modbus.msg.ReadMultipleRegistersResponse;
import net.wimpi.modbus.net.TCPMasterConnection;

/**
 * Creates a basic sensor that read the first hundred registers.
 * 
 * @author Edwin Lim
 * 
 */
public class SensorBasic {

  /**
   * Creates the modbus connection and access the device for the register values.
   * 
   * @param args Command line arguments
   * @throws Exception Stops the program
   */
  public static void main(String[] args) throws Exception {
    // Jamod connections and transaction
    TCPMasterConnection con = null; // the connection
    ModbusTCPTransaction trans = null; // the transaction
    // Read the registers as Function 03 //
    ReadMultipleRegistersRequest req = null; // the request
    ReadMultipleRegistersResponse res = null; // the response
    // Assign command line args to variables
    String host = "localhost";
    InetAddress addr = InetAddress.getByName(host);

    // Variables for storing the parameters
    int port = Modbus.DEFAULT_PORT;
    // All the registers of a meter
    // For particular registers, create a list of the desired registers
    // registers = { 16418, 16419, 16464, 16465};
    Integer[] registers = new Integer[100];
    // the number of consecutive registers to read
    int count = registers.length;
    // Incase of overflow values
    // power[0] = overflow
    // power[1] = value
    Integer[] power = new Integer[2];
    // energy[0] = overflow
    // energy[1] = value
    // Integer[] energy = new Integer[2];

    // initialize arrays to 0
    for (int i = 0; i < power.length; i++) {
      power[i] = 0;
      // energy[i] = 0;
    }
    for (int i = 0; i < count; i++) {
      registers[i] = 0;
      // System.out.println(i);
    }
    // the reference; offset where to start reading from
    // Some meter could start from the register 1
    int ref = 0;

    // Open the connection
    con = new TCPMasterConnection(addr);
    con.setPort(port);
    try {
      con.connect();
    }
    catch (Exception e) {
      System.err.println("Could not connect to device: " + e.getMessage());
    }

    // Prepare the request
    req = new ReadMultipleRegistersRequest(ref, count);

    // Prepare the transaction
    trans = new ModbusTCPTransaction(con);
    trans.setRequest(req);

    // Execute the transaction repeat times
    int k = 0;
    // System.out.println("Connected... " + con.getAddress() +":" + port + "\n ");
    do {

      try {
        trans.execute();
      }
      catch (ModbusIOException e) {
        System.err.println("Could not load ModBus IO: " + e.getMessage());
      }
      catch (ModbusSlaveException e) {
        System.err.println("Could not Connect to the slave: " + e.getMessage());
      }
      catch (ModbusException e) {
        System.err.println("ModBus Exception: " + e.getMessage());
      }

      res = (ReadMultipleRegistersResponse) trans.getResponse();
      registers[k] = res.getRegisterValue(k);
      // System.out.println(k + ": " + registers[k]);
      k++;
    }
    while (k < count);

    int counter = 0;
    for (int i = 0; i < 14; i++) {
      if (counter == registers.length) {
        i = 15;
      }
      if (i == 9) {
        System.out.println();
        i = 0;
      }
      if (counter < registers.length) {
        System.out.print("[" + (counter + 1) + "]: " + registers[counter] + "\t");
      }
      counter++;
    }
    // Close the Modbus connection
    con.close();
  }
}
